#ifndef RSAPPIT_IB_H
#define RSAPPIT_IB_H
#include "base.h"
#include "ibprotocol.h"
#include "hashtable.h"
#include "hashtable.h"
#include "udprequest.h"
#include "udpresponse.h"
#include "udpagent.h"
#include <stdio.h>
#include <math.h>

struct Response
{
  UdpResponse * pRes;
  unsigned long milli;			/* time the packet was last transmitted */
  int count;					/* #times the packet was transmitted */
};

struct TagReq
{
/*   string strTag; */
/*   string strIndKey; */
  int tagid;
  int fileIndex;
  char * buf;
  size_t len;
  int totalblocks;
  string strEncK_Ki;
  bool bDone;					/* already sent */
TagReq(): buf(NULL), bDone(false){}
};

class IB
{
 public:
  IB();
  ~IB();
  void LoadFile(TagReq * pTag);
  bool SendSingleRecordBlocks(TagReq * pTag);
  virtual int OnNewRequest(UdpRequest * pRequest);
  virtual int ReceiveAck();
  void SetHashTable(HashTable * ptable)
  {
	m_pHashTable = ptable;
  }
  void SetUdpAgent(UdpAgent * pUdp)
  {
	m_pUdpAgent = pUdp;
  }
  void SetupUdp(unsigned short port, const struct sockaddr_in& sockaddClient);

 private:
  HashTable * m_pHashTable;
  bool m_bExit;
  list<struct Response> m_listSlidingWindow;
  pthread_mutex_t m_mutexSlidingWindow;
  pthread_cond_t m_cvSlidingWindow;
  UdpAgent * m_pUdpAgent;
  int m_id;
  unsigned long long m_capacity;
  int m_currentTagId;
  deque<TagReq *> m_dqTags;
  char * m_buf;
  size_t m_len;
  int m_reqid;
  int m_subresid;
  int m_blockid;
  int m_totalblocks;
  int m_limit;
};

#endif
